const md5 = require('md5');
const FormData = require('form-data');
const axios = require('axios').default;
const fs = require('fs').promises;
const fetch = require('node-fetch');
const OSS = require('ali-oss');
const token_string = '2qrjfodsau09f34qpjn4jrfw9a8asoidewfoeffdjsalj3jfjadsf89fj3lk'
const dingding_link = 'https://oapi.dingtalk.com/robot/send?access_token=a6b9da27a45943ac19124df4cf8a7ee758b38c077f652385a9509e0be2733a28'
const dingding_tag = '_spider'
exports.dingding_hook = dingding_link
exports.dingding_tag = dingding_tag
let root_uri = 'http://tools.kikimami.com/'
    //console.log(uri)
// const  root_uri = 'http://localhost:5000/'

async function md5_token() {
    const date_ob = new Date()
    let month = date_ob.getUTCMonth()+1
    let today = `${date_ob.getUTCFullYear()}-${(date_ob.getUTCMonth()+1).toString().padStart(2, '0')}-${date_ob.getUTCDate().toString().padStart(2, '0')}`
    let t_a = token_string.split('')
    t_a[date_ob.getUTCDate()] = today
    let token_s = t_a.join('')
    return md5(token_s, {asString: false})
}
async function DingDingMsg(msg, hook, dingding_tag, atMobiles) {

    let uri = hook
    let data = {
        "msgtype": "text",
        "text": {
            "content": msg + '\n------from ' + dingding_tag
        },
        "at": {
            "atMobiles": atMobiles,
            "isAtAll": false
        }
    }
    let v = {
        uri: uri,
        method: 'POST',
        timeout: 2000,
        json: data,
    };
    const result = await axios.post(uri, data)
    return result.data
}
exports.SendDingDingTextMsg = DingDingMsg


async function DingDingMarkDownMsg(title, msg, hook, dingding_tag, atMobiles) {
    let uri = hook
    let data = {
        "msgtype": "markdown",
        "markdown": {
            "title": title,
            "text": msg + '\n------from ' + dingding_tag
        },
        "at": {
            "atMobiles": atMobiles,
            "isAtAll": false
        }
    }
    let v = {
        uri: uri,
        method: 'POST',
        timeout: 2000,
        json: data,
    };
    const result = await axios.post(uri, data)
    return result.data

}
exports.SendDingDingMarkDownMsg = DingDingMarkDownMsg

async function erp_request(data, command, method='POST', api_root_path='erp/api/', token_method) {
    //console.log('send command:' + command + 'to erp')
    let uri = root_uri + api_root_path + command + '/'
    const token = await md5_token()
    const HTTP_AXIOS = await axios.create()
    const headers =  {'TOKEN': token}
    if(method === 'POST') {
        // console.log('use axios')
        try{
            console.log(uri)
            const resp =  await HTTP_AXIOS({
                method: 'post',
                url: uri,
                data: data,
                headers: headers,
                timeout: 60000
              })
            //const resp = await axios.post(uri, data, {headers: headers})
            // console.log(resp)
            return resp.data
        }catch (e) {
            console.log(e)
            return null
        }

    } else if (method === 'PUT') {
        try{
            const resp =  await HTTP_AXIOS({
                method: 'put',
                url: uri,
                data: data,
                headers: headers,
                timeout: 10000
              })
            //const resp = await axios.put(uri, data, {headers: headers})
            return resp.data
        }catch (e) {
            console.log(e)
            return null
        }

    }else {
        console.log('use axios get')
         try{
            const resp =  await HTTP_AXIOS({
                method: 'get',
                url: uri,
                params: data,
                data: data,
                headers: headers,
                timeout: 10000
              })
            //const resp  = await axios.get(uri, {headers: headers, params: data, data: data})

            return resp.data
        }catch (e) {
            console.log(e)
            return null
        }

    }
}
exports.erp_request = erp_request

/**
 * 根据文件内容和mimeType上传文件到服务器
 *
 * @param {Buffer} fileContent 文件的Buffer内容
 * @param {string} mimeType 文件的MIME类型
 * @param {string} uploadUrl 上传文件的服务器端点
 * @param {Object} extraData 任何额外的表单数据
 * @param {string} filename 文件名
 */

async function uploadFileFromContent(filePath, mimeType, uploadUrl, extraData = {}, filename) {
    try {
        const fileContent = await fs.readFile(filePath); // 异步读取文件内容
        const boundary = "----WebKitFormBoundary" + Math.random().toString(16);
        let requestBody = '';

        // 为每个额外的表单数据添加部分
        for (const key in extraData) {
            requestBody += `--${boundary}\r\nContent-Disposition: form-data; name="${key}"\r\n\r\n${extraData[key]}\r\n`;
        }

        // 添加文件部分
        requestBody += `--${boundary}\r\nContent-Disposition: form-data; name="file"; filename="${filename}"\r\nContent-Type: ${mimeType}\r\n\r\n`;
        const payload = Buffer.concat([
            Buffer.from(requestBody, "utf8"),
            fileContent,
            Buffer.from(`\r\n--${boundary}--\r\n`, "utf8"),
        ]);

        const token = await md5_token(); // 获取 md5 token

        // 发送 POST 请求到服务器
        const response = await fetch(root_uri + uploadUrl, {
            method: 'POST',
            body: payload,
            headers: {
                'Content-Type': `multipart/form-data; boundary=${boundary}`,
                'TOKEN': token, // 添加 md5token 到请求头
            },
        });

        if (!response.ok) {
            throw new Error(`Server responded with ${response.status}`);
        }

        const responseData = await response.json();
        console.log('文件上传成功:', responseData);
        return responseData;
    } catch (error) {
        console.error('文件上传失败:', error);
        throw error; // 使调用者能够捕获异常
    }
}

exports.uploadFileFromContent = uploadFileFromContent;


/**
 * 初始化并上传文件到 OSS，然后设置为公共可读
 * @param {String} filePath 本地文件路径
 * @param {String} targetPath OSS 上的目标路径，例如 'folder/subfolder/filename.ext'
 * @param {Object} ossConfig OSS 配置对象
 * @returns {Promise<String>} 文件的公共可读下载链接
 */
async function uploadFileToOSS(fileContent, targetPath, ossConfig) {
  // 根据提供的配置初始化 OSS 客户端
  const client = new OSS({
    endpoint: ossConfig.endpoint,
    accessKeyId: ossConfig.access_key_id,
    accessKeySecret: ossConfig.access_key_secret,
    bucket: ossConfig.bucket_name
  });

  try {
    // 使用 put 方法上传文件
    await client.put(targetPath, fileContent, {
      headers: {
        'x-oss-object-acl': 'public-read' // 设置文件为公共可读
      }
    });

    // 生成并返回文件的公共可读下载链接
    const url = client.signatureUrl(targetPath, { expires: 3600, response: { 'content-disposition': 'attachment' } });
    console.log('文件上传并设置为公共可读成功，下载链接:', url);
    return url;
  } catch (error) {
    console.error('上传到 OSS 失败:', error);
    throw error;
  }
}

exports.uploadFileToOSS = uploadFileToOSS;